﻿using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Linq;
using System.Diagnostics;
using System.Text;
using System.IO;
using USB2XXX;

namespace USB2XXX_CAN_UDSTest
{
    class Program
    {
        static void Main(string[] args)
        {
            USB_DEVICE.DEVICE_INFO DevInfo = new USB_DEVICE.DEVICE_INFO();
            Int32[] DevHandles = new Int32[20];
            Int32 DevHandle = 0;
            Byte CANIndex = 0;
            bool state;
            Int32 DevNum, ret;
            string dllFilePath = "USB2XXX.dll";
            if (!File.Exists(dllFilePath))
            {
                Console.WriteLine("请先将USB2XXX.dll和libusb-1.0.dll文件复制到exe程序文件输出目录下!");
                Console.WriteLine("dll文件在‘usb2can_lin_pwm_example/sdk/libs/windows’目录下！");
                Console.WriteLine("程序是32位的就复制‘x86_32’目录下文件，程序是64位的就复制‘x86_64’目录下文件！");
                return;
            }
            //扫描查找设备
            DevNum = USB_DEVICE.USB_ScanDevice(DevHandles);
            if (DevNum <= 0)
            {
                Console.WriteLine("No device connected!");
                return;
            }
            else
            {
                Console.WriteLine("Have {0} device connected!", DevNum);
            }
            DevHandle = DevHandles[0];
            //打开设备
            state = USB_DEVICE.USB_OpenDevice(DevHandle);
            if (!state)
            {
                Console.WriteLine("Open device error!");
                return;
            }
            else
            {
                Console.WriteLine("Open device success!");
            }
            //获取固件信息
            StringBuilder FuncStr = new StringBuilder(256);
            state = USB_DEVICE.DEV_GetDeviceInfo(DevHandle, ref DevInfo, FuncStr);
            if (!state)
            {
                Console.WriteLine("Get device infomation error!");
                return;
            }
            else
            {
                Console.WriteLine("Firmware Info:");
                Console.WriteLine("    Name:" + Encoding.Default.GetString(DevInfo.FirmwareName));
                Console.WriteLine("    Build Date:" + Encoding.Default.GetString(DevInfo.BuildDate));
                Console.WriteLine("    Firmware Version:v{0}.{1}.{2}", (DevInfo.FirmwareVersion >> 24) & 0xFF, (DevInfo.FirmwareVersion >> 16) & 0xFF, DevInfo.FirmwareVersion & 0xFFFF);
                Console.WriteLine("    Hardware Version:v{0}.{1}.{2}", (DevInfo.HardwareVersion >> 24) & 0xFF, (DevInfo.HardwareVersion >> 16) & 0xFF, DevInfo.HardwareVersion & 0xFFFF);
                Console.WriteLine("    Functions:" + DevInfo.Functions.ToString("X8"));
                Console.WriteLine("    Functions String:" + FuncStr);
            }
            //初始化配置CAN
            USB2CAN.CAN_INIT_CONFIG CANConfig = new USB2CAN.CAN_INIT_CONFIG();
            ret = USB2CAN.CAN_GetCANSpeedArg(DevHandle, ref CANConfig,500000);
            if (ret == USB2CAN.CAN_SUCCESS)
            {
                CANConfig.CAN_Mode = 0 | 0x80;//正常模式,按位或上0x80表示接入内部终端电阻到总线
                ret = USB2CAN.CAN_Init(DevHandle, CANIndex, ref CANConfig);
                if (ret != USB2CAN.CAN_SUCCESS)
                {
                    Console.WriteLine("Config CAN failed!");
                    return;
                }
                else
                {
                    Console.WriteLine("Config CAN Success!");
                }
            }
            else
            {
                Console.WriteLine("Get CAN speed arguments failed!");
                return;
            }
            //循环测试
            for (int t = 0; t < 2; t++)
            {
                //设置请求数据
                CAN_UDS.CAN_UDS_ADDR UDSAddr = new CAN_UDS.CAN_UDS_ADDR();
                UDSAddr.Flag = 0;//使用标准帧
                UDSAddr.AddrFormats = 0;
                UDSAddr.MaxDLC = 8;
                UDSAddr.ReqID = 0x733;//请求ID
                UDSAddr.ResID = 0x73b;//响应ID
                byte[] req_data = new byte[] { 0x22, 0xF1, 0x13 };//第一字节为服务ID(SID)，后面的数据为对应的参数
                byte[] res_data = new byte[4096];
                ret = CAN_UDS.CAN_UDS_Request(DevHandle, CANIndex, ref UDSAddr, req_data, req_data.Length);
                if (ret != CAN_UDS.CAN_UDS_OK)
                {
                    Console.WriteLine("CAN UDS request failed! {0}", ret);
                }
                else
                {
                    Console.Write("Request:");
                    for (int i = 0; i < req_data.Length; i++)
                    {
                        Console.Write(" {0:X2}", req_data[i]);
                    }
                    Console.WriteLine("");
                }
                //获取响应数据，有可能因为设备会进入睡眠模式，若第一次无法正常获取响应，可以延时100ms之后再次请求获取响应
                ret = CAN_UDS.CAN_UDS_Response(DevHandle, CANIndex, ref UDSAddr, res_data, 200);
                if (ret <= CAN_UDS.CAN_UDS_OK)
                {
                    Console.WriteLine("CAN UDS response failed! {0}", ret);
                }
                else
                {
                    Console.Write("Response:");
                    for (int i = 0; i < ret; i++)
                    {
                        Console.Write(" {0:X2}", res_data[i]);//响应数据的第一字节为RSID，正常情况下，RSID=SID+0x40
                    }
                    Console.WriteLine("");
                }
                System.Threading.Thread.Sleep(200);
            }
        }
    }
}
